<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<input type="text" id="inputValue"/>
<button id="btn">打开/创建database</button>
<button id="addBtn">增加</button>
<button id="deleteBtn">删除</button>
<button id="updateBtn">更新</button>
<button id="getBtn">获取</button>
<button id="cursorBtn">使用游标获取全部/getAll</button>
<script>
  // 我们的客户数据看起来像这样。
  const customerData = [
    {ssn: "444-44-4444", name: "Bill", age: 35, email: "bill@company.com"},
    {ssn: "555-55-5555", name: "Donna", age: 32, email: "donna@home.org"},
    {ssn: "666-66-6666", name: "Tony", age: 23, email: "ony@home.org"}
  ];
  let db = null
  const openDatabase = function (version) {
    console.log('database version:', version)
    // 如果数据库不存在，open 操作会创建该数据库,第二个参数指定数据库的版本
    const request = window.indexedDB.open('MySecondDatabase', version)

    request.onsuccess = function (event) {
      db = event.target.result
      console.log('database success')
    }

    request.onerror = function (event) {
      console.log('database fail:', event.target.error.message)
    }

    // 当你创建一个新的数据库或者增加已存在的数据库的版本号（当打开数据库时，指定一个比之前更大的版本号）， onupgradeneeded 事件会被触发
    request.onupgradeneeded = function (event) {
      console.log('database onupgradeneeded')

      // 保存 IDBDataBase 接口
      db = event.target.result
      const objectStore = db.createObjectStore('customers', {keyPath: 'ssn'})
      console.log('database result', db, objectStore)

      // 使用事务的 oncomplete 事件确保在插入数据前对象仓库已经创建完毕
      objectStore.transaction.oncomplete = function () {
        const transaction = db.transaction('customers', 'readwrite')
        const customersObjectStore = transaction.objectStore('customers')
        customerData.forEach(item => {
          customersObjectStore.add(item)
        })
      }
      // 如果 onupgradeneeded 事件成功执行完成，打开数据库请求的 onsuccess 处理函数会被触发。
    }
  }
  btn.addEventListener('click', () => {
    openDatabase(Number(inputValue.value || 1))
  })

  addBtn.addEventListener('click', () => {
    const request = db
      .transaction('customers', 'readwrite')
      .objectStore('customers')
      .add({ssn: "777-77-7777", name: "Aili", age: 27, email: "aili@company.com"})

    request.onsuccess = function () {
      console.log('add ssn 777-77-7777 success')
    }
  })

  deleteBtn.addEventListener('click', () => {
    const request = db
      .transaction('customers', 'readwrite')
      .objectStore('customers')
      .delete('444-44-4444')

    request.onsuccess = function (event) {
      console.log('delete ssn 444-44-4444 success')
    }
  })

  updateBtn.addEventListener('click', () => {
    const transaction = db.transaction('customers', 'readwrite')
    const objectStore = transaction.objectStore('customers')
    const request = objectStore.get('444-44-4444')
    request.onsuccess = function (event) {
      // 先拿到数据
      const data = event.target.result
      data.age = 100
      // 更新数据
      const updateRequest = objectStore.put(data)
      updateRequest.onsuccess = function () {
        console.log('update ssn 444-44-4444 success')
      }
    }
  })

  getBtn.addEventListener('click', () => {
    const transaction = db.transaction('customers')
    const objectStore = transaction.objectStore('customers')
    const request = objectStore.get('444-44-4444')
    request.onsuccess = function (event) {
      console.log('get ssn 444-44-4444:', event.target.result)
    }
  })

  // 使用 get() 要求你知道你想要检索哪一个键。如果你想要遍历对象存储空间中的所有值，那么你可以使用游标
  cursorBtn.addEventListener('click', () => {
    const objectStore = db.transaction('customers').objectStore('customers')
    const data = []
    objectStore.openCursor().onsuccess = function (event) {
      const result = event.target.result
      // 如果你想要保持继续前行，那么你必须调用游标上的 continue() 。
      // 当你已经到达数据的末尾时（或者没有匹配 openCursor() 请求的条目）你仍然会得到一个成功回调，但是 result 属性是 undefined。
      if (result) {
        data.push(result.value)
        result.continue()
      } else {
        console.log("以获取所有客户信息: ");
        console.log(data)
      }
    }

    // 可选地，你可以使用 getAll() 来处理这种情况（以及 getAllKeys()）。下面的代码的效果和上例相同
    objectStore.getAll().onsuccess = function (event) {
      console.log("Got all customers: ")
      console.log(event.target.result);
    };

    /**
     * 查看游标的 value 属性会带来性能消耗，因为对象是被懒生成的。
     * 当你使用 getAll() ，浏览器必须一次创建所有的对象。如果你仅仅想检索m键，那么使用游标将比使用 getAll() 高效得多。
     * 当然如果你想获取一个由对象仓库中所有对象组成的数组，请使用 getAll()。
     */
  })
</script>
</body>
</html>
